/**
 * 软件著作权：东方汇创
 *
 * 系统名称：  工信部OA
 *
 * 文件名称：  FrontFlowDefController.java
 *
 * 功能描述：  前台流程定义Controller
 * 
 * 版本历史：
 * 
 * 2017-03-08   1.0.0版 （龙色波）（创建文件）
 */
package com.dfhc.wk.frontflowdef.web;



import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.apache.commons.collections.CollectionUtils;
import org.quickbundle.base.beans.factory.RmBeanFactory;
import org.quickbundle.base.web.page.RmPageVo;
import org.quickbundle.project.RmProjectHelper;
import org.quickbundle.project.common.vo.RmCommonVo;
import org.quickbundle.tools.helper.RmJspHelper;
import org.quickbundle.tools.helper.RmVoHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.alibaba.fastjson.JSONObject;
import com.dfhc.ISystemConstant;
import com.dfhc.pub.concurrencycontrol.RequestConcurrentRoute;
import com.dfhc.pub.service.IExtGeneralBusinessProcessService;
import com.dfhc.util.StringHelper;
import com.dfhc.wk.frontflowdef.IFrontFlowDefConstants;
import com.dfhc.wk.frontflowdef.service.FrontFlowDefService;
import com.dfhc.wk.frontflowdef.vo.FrontDefTaskVo;
import com.dfhc.wk.frontflowdef.vo.FrontFlowDefVo;
import com.dfhc.wk.generalbusinessprocess.vo.GeneralBusinessProcessVo;
import com.dfhc.wk.tasknodeextconf.vo.TaskNodeExtConfVo;

/**
 * list                  /frontflowdef
 * insert page      GET  /frontflowdef/insert
 * insert action    POST /frontflowdef/insert
 * update page      GET  /frontflowdef/update/{id}
 * update action    POST /frontflowdef/update
 * delete action    POST /frontflowdef/delete
 * detail                /frontflowdef/detail/{id}

 * reference             /frontflowdef/reference
 * import page      GET  /frontflowdef/import
 * import action    POST /frontflowdef/import
 * export custom    GET  /frontflowdef/export
 * export action    POST /frontflowdef/export
 */

/**
 * 前台流程定义 Controller
 * 
 * @author 龙色波
 * @see 参见的类
 */
@Controller
@RequestMapping(value = "/frontflowdef")
public class FrontFlowDefController implements IFrontFlowDefConstants {

    @Autowired
    /**
     * 前台流程定义服务
     */
    private FrontFlowDefService frontFlowDefService;
    @Autowired
    /**
     * 前台流程定义服务
     */
    private TaskService taskService;
    
    /**
     * 简单查询，分页显示，支持表单回写
     * @param model 模型
     * @param request http请求对象
     * @return 跳转的列表jsp     
     */
    @RequestMapping(value = "")
    public String list(Model model, HttpServletRequest request) {
        model.addAttribute(ISystemConstant.RM_PARENT_CODE, request.getParameter(ISystemConstant.RM_PARENT_CODE));  //把模块代码放入request     
        return "/miit/wk/frontflowdef/listFrontFlowDef";
    }
   
    /**
     * ajax 请求列表数据
     * @param model
     * @param request
     * @return
     * @throws IOException 
     */
    @RequestMapping(value = "ajaxList")
    public void ajaxList(Model model, HttpServletRequest request, HttpServletResponse response) throws IOException{
        Map<String,Object> dataMap=new HashMap<String,Object>();
        
        String page=request.getParameter("page")==null?"1":request.getParameter("page");
        String rows=request.getParameter("rows")==null?ISystemConstant.DEFAULT_PAGE_SIZE:request.getParameter("rows");
        int rowsInt=Integer.parseInt(rows);//页大小
        int pageInt=Integer.parseInt(page);//当前页
        Map<String, Object> searchPara = getQueryCondition(request);  //从request中获得查询条件
        RmPageVo pageVo = RmJspHelper.transctPageVo(request, frontFlowDefService.getCount(searchPara));
        pageVo.setPageSize(rowsInt);
        pageVo.setCurrentPage(pageInt);
        String orderStr = RmJspHelper.getOrderStr(request);  //得到排序信息
        if(StringHelper.isEmpty(orderStr)){
            String sidx=request.getParameter("sidx")==null?"id":request.getParameter("sidx");
            String sord=request.getParameter("sord")==null?"desc":request.getParameter("sord");
            orderStr=sidx+" "+sord;
        }
        
        List<FrontFlowDefVo> beans = frontFlowDefService.list(searchPara, orderStr, pageVo.getStartIndex(), pageVo.getPageSize());  //按条件查询全部,带排序
         
        dataMap.put("page",  pageVo.getCurrentPage());
        dataMap.put("total",  pageVo.getPageCount());
        dataMap.put("records",  pageVo.getRecordCount());
        dataMap.put("rows", beans);
         
        response.setCharacterEncoding("UTF-8"); 
        response.getWriter().write(JSONObject.toJSONString(dataMap));
    }
    
    /**
     * 从页面表单获取信息注入vo，并插入单条记录
     * @param request http请求对象
     * @param vo 值对象
     * @return 返回Ajax应答实体对象
     */
    @RequestMapping(value = "insert", method = RequestMethod.POST, 
			consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String,Object> insert(HttpServletRequest request, @Valid FrontFlowDefVo vo) {
        RmVoHelper.markCreateStamp(request,vo);  //打创建时间,IP戳
        frontFlowDefService.insert(vo);  //插入单条记录
        Map<String, Object> result = new HashMap<String, Object>();
        result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
        result.put(ISystemConstant.AJAX_MESSAGE, "新增成功: " + vo.getId());
        return result;
    }
    
    /**
     * 从页面表单获取信息注入vo，并修改单条记录
     * @param request 请求对象
     * @param vo 值对象
     * @param errors Ajax错误对象
     * @return 返回Ajax应答实体对象
     */
    @RequestMapping(value = "update", method = RequestMethod.POST, 
			consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String,Object> update(HttpServletRequest request, @Valid FrontFlowDefVo vo) {
        RmVoHelper.markModifyStamp(request,vo);  //打修改时间,IP戳
        frontFlowDefService.update(vo);  //更新单条记录
        Map<String, Object> result = new HashMap<String, Object>();
        result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
        result.put(ISystemConstant.AJAX_MESSAGE, "修改成功: " + vo.getId());
        return result;
    }
    /**
     * 根据id获取单条记录
     * @param request 请求对象
     * @param vo 值对象
     * @param
     * @return 返回Ajax应答实体对象
     */
    @RequestMapping(value = "get/{id}/{dateTime}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String,Object> get(@PathVariable("id") String id, HttpServletRequest request) {
        FrontFlowDefVo bean = frontFlowDefService.get(id);
        Map<String, Object> result = new HashMap<String, Object>();
        if(bean==null){
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, "记录没找到(id:"+id+")!");
            return result;
        }
        
        result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
        result.put(ISystemConstant.AJAX_BEAN, bean);
        return result;			
    }    
    /**
     * 从页面的表单获取单条记录id并删除，如request.id为空则删除多条记录（request.ids）
     * @param request http请求对象
     * @param redirectAttributes 重定向属性
     * @return 返回列表页面
     */
    @RequestMapping(value = "delete", method = RequestMethod.POST)
    public String delete(HttpServletRequest request, RedirectAttributes redirectAttributes) {
        int deleteCount = 0;  //定义成功删除的记录数
        String id = request.getParameter(REQUEST_ID);
        if(id != null && id.length() > 0) {
            deleteCount = frontFlowDefService.delete(new String(id));
        } else {
            String[] ids = RmJspHelper.getArrayFromRequest(request, REQUEST_IDS); //从request获取多条记录id
            if (ids != null && ids.length != 0) {
                deleteCount += frontFlowDefService.delete(ids);  //删除多条记录
            }
        }
        redirectAttributes.addFlashAttribute("message", "删除成功: " + deleteCount);
        return "redirect:/frontflowdef?"+ISystemConstant.RM_PARENT_CODE+"="+request.getParameter(ISystemConstant.RM_PARENT_CODE);
    }
   /**
     * 从页面的表单获取单条记录id并逻辑删除，如request.id为空则删除多条记录（request.ids）
     * @param request http请求对象
     * @param redirectAttributes 重定向属性
     * @return 返回列表页面
     */
    @RequestMapping(value = "logicDelete", method = RequestMethod.POST)
    public String deleteLogic(HttpServletRequest request, RedirectAttributes redirectAttributes) {
        int deleteCount = 0;  //定义成功删除的记录数
        String id = request.getParameter(REQUEST_ID);
        if(id != null && id.length() > 0) {
            deleteCount = frontFlowDefService.deleteLogic(request,new String(id));
        } else {
            String[] ids = RmJspHelper.getArrayFromRequest(request, REQUEST_IDS); //从request获取多条记录id
            if (ids != null && ids.length != 0) {
                deleteCount += frontFlowDefService.deleteLogic(request,ids);  //删除多条记录
            }
        }
        redirectAttributes.addFlashAttribute("message", "删除成功: " + deleteCount);
        return "redirect:/frontflowdef?"+ISystemConstant.RM_PARENT_CODE+"="+request.getParameter(ISystemConstant.RM_PARENT_CODE);
    }
    /**
     * 从页面的表单获取单条记录id，并察看这条记录的详细信息
     * @param id 待删除的id
     * @param model 模型
     * @request 请求对象
     * @return 返回详细信息页面
     */
    @RequestMapping(value = "detail/{id}")
    public String detail(@PathVariable("id") String id, Model model, HttpServletRequest request) {
        FrontFlowDefVo bean = frontFlowDefService.get(id);
        model.addAttribute(REQUEST_BEAN, bean);  //把vo放入request
        if(RM_YES.equals(request.getParameter(REQUEST_IS_READ_ONLY))) {
            model.addAttribute(REQUEST_IS_READ_ONLY, request.getParameter(REQUEST_IS_READ_ONLY));
        }
        return "/miit/wk/frontflowdef/detailFrontFlowDef";
    }

    /**
     * 参照信息查询，带简单查询，分页显示，支持表单回写
     * @param model 模型
     * @param request http请求对象
     * @return 返回参照列表页面
     */
    @RequestMapping(value = "reference")
    public String reference(Model model, HttpServletRequest request) {
        model.addAttribute(REQUEST_REFERENCE_INPUT_TYPE, request.getParameter(REQUEST_REFERENCE_INPUT_TYPE));  //传送输入方式,checkbox或radio
        return "/miit/wk/frontflowdef/util/referenceFrontFlowDef";
    }
    /**
     * 参照改为ajax
     * @param model
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping(value = "referenceAjax")
    public void referenceAjax(Model model, HttpServletRequest request, HttpServletResponse response) throws IOException {
    	ajaxList(model, request, response);//ajax yemian 
    }
    /**
     * 跳转到导入页
     * @param model 模型
     * @return 返回导入页
     */
    @RequestMapping(value = "import", method = RequestMethod.GET)
    public String importDataForm(Model model) {
        return "/miit/wk/frontflowdef/importFrontFlowDef";
    }
    
    /**
     * 执行导入
     * @param model 模型
     * @return 返回导入页面
     */
    @RequestMapping(value = "import", method = RequestMethod.POST)
    public String importData(Model model) {
        model.addAttribute("isSubmit", "1");
        return "/miit/wk/frontflowdef/importFrontFlowDef";
    }
    
    /**
     * 定制导出
     * @param model 模型
     * @return 返回导出页面
     */
    @RequestMapping(value = "export", method = RequestMethod.GET)
    public String exportCustomForm(Model model) {
        return "/miit/wk/frontflowdef/exportFrontFlowDef_custom";
    }
    
    /**
     * 执行导出
     * @param model 模型
     * @return 返回导出xls页面
     */
    @RequestMapping(value = "export", method = RequestMethod.POST)
    public String exportData(Model model) {
        return "/miit/wk/frontflowdef/exportFrontFlowDef_excel";
    }

    /**
     * 从request中获得查询条件
     * @param request http请求对象
     * @return 条件Map
     */
    public static Map<String, Object> getQueryCondition(HttpServletRequest request) {
        Map<String, Object> searchMap = null;
        if(request.getAttribute(REQUEST_QUERY_CONDITION) != null) {  //如果request.getAttribute中有，就不取request.getParameter
            searchMap = (Map<String, Object>)request.getAttribute(REQUEST_QUERY_CONDITION);
        } else {
           searchMap = new HashMap<String, Object>();
           searchMap.put("id", request.getParameter("id"));
           searchMap.put("procName", request.getParameter("procName"));
           searchMap.put("procDefId", request.getParameter("procDefId"));
           searchMap.put("procDefContent", request.getParameter("procDefContent"));
           searchMap.put("remark", request.getParameter("remark"));
           searchMap.put("delete_flag",ISystemConstant.DICTIONARY_RM_YES_NOT_0);
        }
        return searchMap;
    }
   /**
     * 详情页
     * 
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value="toDetail")
    public String toDetail(Model model, HttpServletRequest request){    	
    	String id=request.getParameter("id");
    	
    	FrontFlowDefVo vo=frontFlowDefService.get(id);
    	
    	model.addAttribute("frontFlowDefVo", vo);
    	
    	model.addAttribute("id", id);    
    	return "/miit/wk/frontflowdef/detailFrontFlowDef";    	
    }
    
    /**
     * 展示通用待办列表
     * @param model
     * @param request
     * @return 
     */
    @RequestMapping(value = "listTask")
    public String listTask(Model model, HttpServletRequest request) {
        model.addAttribute(ISystemConstant.RM_PARENT_CODE, request.getParameter(ISystemConstant.RM_PARENT_CODE));  //把模块代码放入request     
        return "/qb5activiti/base/price/listTask";
    }
    
    /**
     * ajax 请求列表数据
     * @param model
     * @param request
     * @return
     * @throws IOException 
     */
    @RequestMapping(value = "ajaxListTask")
    public void ajaxListTask(Model model, HttpServletRequest request, HttpServletResponse response) throws IOException{
        Map<String,Object> dataMap=new HashMap<String,Object>();
        
        String page=request.getParameter("page")==null?"1":request.getParameter("page");
        String rows=request.getParameter("rows")==null?ISystemConstant.DEFAULT_PAGE_SIZE:request.getParameter("rows");
        int rowsInt=Integer.parseInt(rows);//页大小
        int pageInt=Integer.parseInt(page);//当前页 
        
        String userId = RmProjectHelper.getRmUserId(request);
        List<Task> results = frontFlowDefService.findTodoTasks(userId);
        RmPageVo pageVo = RmJspHelper.transctPageVo(request, results.size());
        pageVo.setPageSize(rowsInt);
        pageVo.setCurrentPage(pageInt);
        List<Task> list = new ArrayList<Task>();
        int totalNum = pageVo.getStartIndex()-1+pageVo.getPageSize();
  	  	if(pageVo.getStartIndex()+pageVo.getPageSize()>pageVo.getRecordCount()){
  	  		totalNum = pageVo.getRecordCount();
  	  	}
  	  	for(int i=pageVo.getStartIndex()-1; i<totalNum; i++){
  	  		list.add(results.get(i));
  	  	}
  	  	List<FrontDefTaskVo> beans = new ArrayList<FrontDefTaskVo>();
  	  	for (Task task : list) {
  	  		FrontDefTaskVo priceInstanceVo = new FrontDefTaskVo();
  	  		String processDefinitionId = task.getProcessDefinitionId();
  	  		String processInstanceId = task.getProcessInstanceId();
  	  		priceInstanceVo.setTaskId(task.getId());
  	  		priceInstanceVo.setTaskName(task.getName());
  	  		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  	  		priceInstanceVo.setTaskCreateTime(sdf.format(task.getCreateTime()));
  	  		priceInstanceVo.setProcessDefinitionId(processDefinitionId);
  	  		priceInstanceVo.setProcessInstanceId(processInstanceId);
  	  		
  	  		
  	  		String formId = (String) taskService.getVariable(task.getId(), "formId");
  	  		String formUrl = (String)taskService.getVariable(task.getId(), "formUrl");
  	  		if(!StringHelper.isEmpty(formUrl)){
  	  			String id = formUrl.substring(formUrl.indexOf("{"), formUrl.indexOf("}")+1);
  	  			formUrl = formUrl.replace(id, formId);
  	  		}
  	  		priceInstanceVo.setDoubleParameter(task.getId()+"@"+task.getAssignee()+"@"+formUrl);
  			priceInstanceVo.setFormId(formId);
  			priceInstanceVo.setFormUrl(formUrl);
  	  	
  			beans.add(priceInstanceVo);
		}
         
        dataMap.put("page",  pageVo.getCurrentPage());
        dataMap.put("total",  pageVo.getPageCount());
        dataMap.put("records",  pageVo.getRecordCount());
        dataMap.put("rows", beans);

        response.setCharacterEncoding("UTF-8"); 
        response.getWriter().write(JSONObject.toJSONString(dataMap));
    }
    
    /**
     * 展示通用待办列表
     * @param model
     * @param request
     * @return 
     */
    @RequestMapping(value = "taskShow")
    public String taskShow(Model model, HttpServletRequest request) {
    	
    	String formUrl = request.getParameter("formUrl");
    	String taskId = request.getParameter("taskId");
    	if(StringHelper.isEmpty(formUrl)){
    		 return "redirect:/frontflowdef/listTask";
    	}
    			
        model.addAttribute("formUrl",formUrl); 
        model.addAttribute("taskId",taskId);
        return "/qb5activiti/base/price/taskShow";
    }
    
    
    /**
     * 签收任务
     */
    @RequestMapping(value = "claim/{id}")
    public String claim(@PathVariable("id") String taskId, HttpServletRequest request, RedirectAttributes redirectAttributes,HttpServletResponse response) {
    	boolean bLock = false;
    	try{
	    	bLock = RequestConcurrentRoute.getSingleton().lock(request.getParameter(ISystemConstant.JSGUID));    
	        String userId = RmProjectHelper.getRmUserId(request);
	        //如果传个性化服务id		  	
	  		String serviceBeanId = request.getParameter(ISystemConstant.PREDEFINED_SERVICE_BEAN_ID);
	  		if(!StringHelper.isEmpty(serviceBeanId)){
	  			IExtGeneralBusinessProcessService  generalBusinessService = (IExtGeneralBusinessProcessService) RmBeanFactory.getBean(serviceBeanId);
	 			generalBusinessService.doClaim(request, response);  			
	  		}else{
	  			taskService.claim(taskId, userId);  			
	  		}
	
	        String jspUrl = request.getParameter(ISystemConstant.PREDEFINED_JSP_URL);
	        if(StringHelper.isEmpty(jspUrl)){
		        redirectAttributes.addFlashAttribute("message", "任务已签收");
		        return "redirect:/frontflowdef/listTask";
	        }else{
	        	return jspUrl.trim();
	        }
        }finally{
	        //最后解锁
	        RequestConcurrentRoute.getSingleton().unLock(request.getParameter(ISystemConstant.JSGUID), bLock);
        }	        
    }
    /**
     * 完成任务
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "complete/{id}", method = {RequestMethod.POST, RequestMethod.GET})
    public String complete(@PathVariable("id") String taskId,HttpServletRequest request) {
    	Task task = (Task) taskService.createTaskQuery().taskId(taskId).singleResult();
        //审核意见
        String auditOpinion = request.getParameter(ISystemConstant.PREDEFINED_AUDIT_OPINION);
        if(!StringHelper.isEmpty(auditOpinion)){
        	taskService.addComment(taskId, task.getProcessInstanceId(), auditOpinion);
        }
        
		frontFlowDefService.insertComplete(taskId,request);
		return "redirect:/price/listTask";
    }
    /**
     * 完成任务
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "monitoring", method = {RequestMethod.POST, RequestMethod.GET})
    public String monitoring( HttpServletRequest request, HttpServletResponse response) {
    	
    	//查出对应的form对应的流程实例ID
    	String formId = request.getParameter("formId");
    	String sourceUrl = request.getParameter("sourceUrl");
    	if(StringHelper.isEmpty(formId)){
    		return "redirect:"+sourceUrl;
    	}
    	
    	String sql = "select PROC_INST_ID_ as procInstId,TEXT_ as text from act_ru_variable where TEXT_ = '"+formId+"'";
    	
    	List<RmCommonVo> variables = RmProjectHelper.getCommonServiceInstance().doQuery(sql);
    	if(CollectionUtils.isEmpty(variables)){
    		return "redirect:"+sourceUrl;
    	}
    	String procInstId =(String) variables.get(0).get("procInstId");
    	sql = "select PROC_DEF_ID_ as procDefId,PROC_INST_ID_ as procInstId from act_ru_execution where  PROC_INST_ID_='"+procInstId+"'";
    	
    	List<RmCommonVo> executions = RmProjectHelper.getCommonServiceInstance().doQuery(sql);
    	if(CollectionUtils.isEmpty(executions)){
    		return "redirect:"+sourceUrl;
    	}
    	String procDefId = (String) executions.get(0).get("procDefId");
    	
		return "redirect:/workflow/diagram-viewer/index.html?processDefinitionId="+procDefId+"&processInstanceId="+procInstId;
    }
    
}
